<?php
/**
 * Created by PhpStorm.
 * User: liiyu
 * Date: 2018/6/7
 * Time: 1:51
 */

namespace app\api\controller\v2;

use app\api\controller\v4\CheckOrders;
use app\api\controller\v9\OrdersPay;
use app\common\cachemodel\MallGoodsAttr;
use app\common\cachemodel\Orders as OrdersCacheModel;
use app\common\lib\exception\ApiException;
use app\common\lib\Orders as OrdersLib;
use app\common\model\Orders as OrdersModel;
use app\common\model\Recode;
use app\common\model\Rectification;
use Exception;
use think\Db;
use think\Log;
use think\response\Json;

/**
 * 每日运势订单接口
 * Class Orders
 * @package app\api\controller\v2
 */
class Orders extends Auth
{
    protected $restActionList = ['index', 'read', 'save', 'update', 'delete'];

    protected $msg;

    /**
     * 订单列表
     * @return Json
     * @throws Exception
     */
    public function index()
    {
        if (!request()->isGet())
        {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $page = input('get.page/d', 1);

        $type = input('get.type/d', 0);

        $uid = $this->user['id'];

        //        判断是否超时
        check_overtime($uid);

        $OrderModel = new OrdersModel();
        $RecodeModel = new Recode();

        $orders = $OrderModel->getUidOrders(['uid' => $uid, 'type' => $type, 'is_del' => 0, 'page' => $page]);

        //将数据根据创建时间排序
        array_multisort(array_column($orders, 'create_time'), SORT_NUMERIC, SORT_DESC, $orders);
        $data = [];
        //重组订单数据
        if (isset($orders) || !empty($orders))
        {
            foreach ($orders as $k => $v)
            {
                if ($v['gid'] == 1)
                {
                    if ($this->is_apple_pay)
                    {
                        $rec_or_price = $this->apple_goods['rec_goods']['or_prize'];
                        $rec_now_price = $this->apple_goods['rec_goods']['now_prize'];
                    } else
                    {
                        $rec_or_price = $v['or_prize'];
                        $rec_now_price = $v['now_prize'];
                        //商品活动折扣
                        $activeDiscount = active($v['gid']);
                        if ($activeDiscount['discount'] && !$this->is_apple_pay)
                        {
                            $rec_now_price *= $activeDiscount['discount'];
                        }
                    }

                    $data[] = [
                        'type' => 1,
                        'id' => $v['reid'],
                        'status' => $v['restatus'],
                        'start_time' => $v['start_time'],
                        'end_time' => $v['end_time'],
                        'create_time' => $v['create_time'],
                        'order_id' => $v['order_id'],
                        'or_prize' => $rec_or_price,
                        'now_prize' => $rec_now_price,
                        'trade_type' => $v['trade_type'],
                        'count' => 1,
                        'total_price' => $v['total_amount']
                    ];
                } elseif (1 < $v['gid'] && $v['gid'] < 7)
                {
                    if ($this->is_apple_pay)
                    {
                        foreach ($this->apple_goods['fortune_day_goods'] as $fortune_day_good)
                        {
                            if ($fortune_day_good['id'] == $v['gid'])
                            {
                                $day_or_price = $fortune_day_good['or_prize'];
                                $day_now_price = $fortune_day_good['now_prize'];
                            }
                        }
                    } else
                    {
                        $day_or_price = $v['or_prize'];
                        $day_now_price = $v['now_prize'];
                        //商品活动折扣
                        $activeDiscount = active($v['gid']);
                        if ($activeDiscount['discount'] && !$this->is_apple_pay)
                        {
                            $day_now_price *= $activeDiscount['discount'];
                        }
                    }

                    $array = [];
                    foreach (explode(',', $v['rids']) as $kk => $vv)
                    {
                        $rname = $RecodeModel->getRecode(['uid' => $this->user['id'], 'id' => $vv]);
                        $array[] = [
                            'id' => $rname['id'],
                            'rname' => $rname['name'],
                            'name' => $v['name'],
                            'start_time' => $v['time'],
                            'end_time' => strtotime($v['expire_time'], $v['time']) - 86400,
                            'or_price' => $day_or_price,
                            'now_price' => $day_now_price
                        ];
                    }
                    $data[] = [
                        'type' => 2,
                        'data' => $array,
                        'create_time' => $v['create_time'],
                        'order_id' => $v['order_id'],
                        'status' => $v['status'],
                        'trade_type' => $v['trade_type'],
                        'count' => count($array),
                        'total_price' => $v['total_amount']
                    ];
                }
            }
        }

        // 统计有多少评论
        $total = count($data);
        //获取数据分页信息
        $per_page = 20;// 当前文章评论每页显示数量
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的数据
        $data_list['data'] = array_slice($data, $data_list['start'], $per_page);
        unset($data_list['start']);
        unset($data_list['end']);

        return show(config('code.success'), '加载成功', $data_list);
    }

    /**
     * 订单详情
     * @return Json
     * @throws ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function read()
    {
        if (!request()->isGet())
        {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $param = request()->param();

        $validate = validate('Orders');

        //验证请求参数
        if ($validate->scene('read')->check($param) !== true)
        {
            return show(config('code.error'), (string)$validate->getError());
        }

        $order_id = $param['order_id'];

        //支付客户端判断该订单是否已经支付,若已经支付,但是status=0;就更改status=1
        (new OrdersLib())->validateOrders($order_id);
        $where = ['or.is_del' => 0, 'order_id' => ['eq', $order_id]];

        $field = 'or.status,or.create_time,or.order_id,or.trade_type,or.gid,or.total_amount,or.pay_time,or.return_time,go.name,go.or_prize,go.now_prize,go.expire_time gtime,fr.id,fr.rids,fr.time ftime';

        $OrdersModel = new OrdersModel();

        try
        {
            $data = $OrdersModel
                ->alias('or')
                ->field($field)
                ->join('app_goods go', 'or.gid=go.id')
                ->join('app_fortune fr', 'or.fid=fr.id')
                ->where($where)
                ->findOrFail();
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '获取订单详情数据失败');
        }
        $arr = [];
        if ($data)
        {
            $arr['status'] = $data['status'];
            foreach (explode(',', $data['rids']) as $k => $v)
            {
                try
                {
                    $rname = Db::table('app_recode')->where('id', $v)->field('id,name')->find();
                }
                catch (Exception $e)
                {
                    return show(config('code.error'), '获取档案失败');
                }
                //判断是否是applePay
                $or_price = 0;
                $now_price = 0;
                if ($this->is_apple_pay)
                {
                    foreach ($this->apple_goods['fortune_goods'] as $ap)
                    {
                        if ($data['gid'] == $ap['id'])
                        {
                            $or_price = $ap['or_prize'];
                            $now_price = $ap['now_prize'];
                        }
                    }
                } else
                {
                    $or_price = $data['or_prize'];
                    $now_price = $data['now_prize'];
                    //商品活动折扣
                    $activeDiscount = active($data['gid']);
                    if ($activeDiscount['discount'] && !$this->is_apple_pay)
                    {
                        $now_price *= $activeDiscount['discount'];
                    }
                }

                $arr['fortune'][] = [
                    'id' => $rname['id'],
                    'gid' => $data['gid'],
                    'rname' => $rname['name'],
                    'name' => $data['name'],
                    'start_time' => $data['ftime'],
                    'end_time' => strtotime($data['gtime'], $data['ftime']) - 86400,
                    'or_price' => $or_price,
                    'now_price' => $now_price
                ];
            }

            $count_rids = count(json_decode($data['rids'], true));
            $arr['count'] = $count_rids;
            $arr['or_total_price'] = sprintf('%.2f', $count_rids * $data['or_prize']);
            $arr['total_price'] = sprintf('%.2f', $data['total_amount']);
            $arr['trade_type'] = $data['trade_type'];
            $arr['order_id'] = $order_id;
            $arr['create_time'] = date('Y-m-d H:i:s', $data['create_time']);

            if ($data['pay_time'])
            {
                $arr['order'][] = [
                    'name' => '支付时间',
                    'value' => date('Y-m-d H:i:s', $data['pay_time']),
                ];
            }
            if ($data['return_time'])
            {
                $arr['order'][] = [
                    'name' => '退款时间',
                    'value' => date('Y-m-d H:i:s', $data['return_time']),
                ];
            }
        }

        return show(200, '成功', $arr);
    }

    /**
     * 删除订单
     * @return Json
     * @throws \think\Exception
     */
    public function del()
    {
        if (!request()->isDelete())
        {
            return show(config('code.error'), '未知操作', [], 403);
        }
        $param['order_id'] = input('order_id', '');
        if (!$param['order_id'])
        {
            return show(config('code.error'), '未知的订单');
        }
        //判断当前订单是否存在
        $OrdersModel = new OrdersCacheModel();
        $orders = $OrdersModel->getInfoById($param['order_id'], ['status', 'reid', 'order_type', 'extend', 'gid', 'fid']);
        if (!$orders)
        {
            return show(config('code.error'), '订单不存在');
        }
        $orders['order_id'] = $param['order_id'];
        //若当前为校准生辰订单,则将校准生辰历史记录也删除
        $num = substr($param['order_id'], 1, 1);
        if ($num == 1)
        {
            Rectification::update(['is_del' => 1], ['id' => $orders['reid']]);
        }
        //删除2.0订单缓存
        $OrdersModel->DelData($param['order_id'], ['is_del' => 1]);
        //订单未支付时关闭订单或还原商品库存
        if ($orders && $orders['status'] == 0)
        {
            \app\common\cachemodel\OrdersLib::CloseOrder($orders);
        }
        return show(config('code.success'), '删除成功');

    }

    /**
     * 解锁每日运势
     * @return Json
     * @throws Exception
     */
    public function pay_unlock()
    {
        if (!request()->isPost())
        {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $param['rids'] = input('param.rids/s', '');
        $param['time'] = input('param.time', 0);
        $param['trade_type'] = input('param.trade_type/d', 0);
        $param['gid'] = input('param.gid/d', 0);
        $param['openid'] = $openid = input('param.openid/s', '');
        //检测下单参数
        $this->CheckUnlock($param);
        if ($this->msg)
        {
            Log::write('v2运势下单请求参数有误：' . $this->msg, 'notice', true);
            return show(config('code.error'), $this->msg);
        }
        $validate = validate('Orders');

        if (!$validate->scene('v2_pay_unlock')->check($param))
        {
            return show(config('code.error'), (string)$validate->getError());
        }

        $trade_type = $param['trade_type'];// 支付方式
        $gid = $param['gid'];// 商品类型id   1=>校准生辰
//        解锁每日运势,生成订单和每日运势表数据
        $rids = $param['rids'];// 选择的档案id，字符串
        $callback_url = input('param.callback_url', '');

        $start_time = date('Y-m-d', $param['time']);// 选择的解锁日期

        //下单统一
        $OrderPayModel = new OrdersPay();
        try
        {
            $data = $OrderPayModel->pay_unlock(['order_type' => 2, 'trade_type' => $trade_type, 'gid' => $gid, 'fortune_type' => 1, 'rids' => $rids, 'start_time' => $start_time, 'openid' => $openid, 'callback_url' => $callback_url]);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '下单失败');
        }

        if ($data['status'] === true)
        {
            return show(config('code.success'), '下单成功', $data['data']);
        }

        return show(config('code.error'), '下单失败', $data['data']);
    }

    /**
     * 订单重新支付
     * @return Json
     * @throws \app\common\lib\exception\ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws Exception
     */
    public function pay_again()
    {
        if (!request()->isPost())
        {
            return show(config('code.error'), '未知操作', [], 403);
        }

        $param = request()->param();

        $validate = validate('Orders');

        if ($validate->scene('pay_again')->check($param) !== true)
        {
            return show(config('code.error'), json_encode($validate->getError(), true));
        }

        $trade_type = $param['trade_type'];// 支付方式

        $order_id = $param['order_id'];// 订单编号

        $openid = input('param.openid', '');// openid

        $callback_url = $param['callback_url'] ?? '';

        $OrdersLib = new OrdersLib();

        //支付客户端判断该订单是否已经支付,若已经支付,但是status=0;就更改status=1
        $validateResult = $OrdersLib->validateOrders($order_id);

        if ($validateResult !== true)
        {
            return show(config('code.error'), $validateResult);
        }

        $num = substr($order_id, 1, 1);

        $OrdersModel = new OrdersModel();
        $CheckOrders = new CheckOrders();
        $RecodeModel = new Recode();
        //检测当前订单是否存在
        try
        {
            $where = ['o.order_id' => $order_id, 'o.is_del' => 0];
            $orders = $OrdersModel
                ->alias('o')
                ->field('o.id,o.total_amount,og.rid orid,re.rid rrid,f.rids,o.gid,og.gid ogid,o.status')
                ->join('wechat_backup_07_18_14_43_00.app_orders_goods og', 'o.id=og.oid', 'LEFT')
                ->join('wechat_backup_07_18_14_43_00.app_fortune f', 'o.fid=f.id', 'LEFT')
                ->join('wechat_backup_07_18_14_43_00.app_rectification re', 'o.reid=re.id', 'LEFT')
                ->where($where)
                ->selectOrFail();
            $orders = json_decode(json_encode($orders, true), true);
        }
        catch (Exception $e)
        {
            return show(config('code.error'), '当前订单不存在');
        }

        $oid = 0;
        if ($orders)
        {
            $total_amount = 0;
            $gid = [];
            foreach ($orders as $order)
            {
                //     0=>未支付  1=>等待计算|等待矫正   2=>交易关闭   3=>退款成功  4=>计算成功|矫正成功|已支付
                $status = (int)$order['status'];
                switch (true)
                {
                    case in_array($status, [1, 4], true):
                        return show(config('code.error'), '订单已支付');
                        break;
                    case $status === 2:
                        return show(config('code.error'), '订单已关闭');
                    default:
                        break;
                }
                //判断购买的档案的订单是否被删除
                switch ($num)
                {
                    case 1:
                        $rid = $order['rrid'];
                        $recode = $RecodeModel->getRecode(['uid' => $this->user['id'], 'id' => $rid]);
                        if ($recode['status'] == 0 || !$recode['status'])
                        {
                            return show(config('code.error'), '该订单的档案已删除，无法支付');
                        }
                        break;
                    case 2:
                        $rids = explode(',', $order['rids']);
                        foreach ($rids as $rid)
                        {
                            $recode = $RecodeModel->getRecode(['uid' => $this->user['id'], 'id' => $rid]);
                            if ($recode['status'] == 0 || !$recode['status'])
                            {
                                return show(config('code.error'), '该订单有档案已删除，无法支付');
                            }
                        }
                        break;
                    case 3:
                        $rid = $order['orid'];
                        $recode = $RecodeModel->getRecode(['uid' => $this->user['id'], 'id' => $rid]);
                        if ($recode['status'] == 0 || !$recode['status'])
                        {
                            return show(config('code.error'), '该订单的档案已删除，无法支付');
                        }
                        break;
                }

                if (!$order['gid'])
                {
                    $gid[] = 'apple_pay_' . $order['ogid'];
                } else
                {
                    $gid[0] = 'apple_pay_' . $order['gid'];
                }

                $total_amount = $order['total_amount'];
                $oid = $order['id'];
            }


            // 检查商品是否已经购买
            $CheckOrders->check_old_orders($order_id);
            switch ($num)
            {
                case 1:
                    $pay_des = '准了 - 校准生辰';
                    break;
                case 2:
                    $pay_des = '准了 - 运势';
                    break;
                case 3:
                    $pay_des = '准了 - 幸运之城';
                    break;
                case 4:
                    $pay_des = '准了 - 教学视频';
                    break;
                case 5:
                    $pay_des = '准了 - 一生报告';
                    break;
                case 6:
                    $pay_des = '准了 - 会员';
                    break;
                default :
                    $pay_des = '';
            }

            /**
             * $account int 下单使用的商户配置id
             * 支付方式   1=>支付宝，2=>微信支付，5=>京东支付，6=>微信公众号支付，7=>支付宝手机网页支付，8=>微信H5网页支付
             */
            switch ($trade_type)
            {
                case 1:
                    $account = (int)config('alipay.default');
                    break;
                case 2:
                    $account = (int)config('wxpay.default');
                    break;
                case 5:
                    $account = (int)config('jdpay.default');
                    break;
                case 6:
                    $account = (int)config('wxpay.default');
                    break;
                case 7:
                    $account = (int)config('alipay.default');
                    break;
                case 8:
                    $account = (int)config('wxpay.default');
                    break;
                default:
                    $account = 1;
                    break;
            }

            /**
             * 更新支付方式 和 当前使用的支付配置
             */
            try
            {
//                $OrdersModel->where(['order_id' => $order_id])->update(['trade_type' => $trade_type, 'account' => $account]);
                (new OrdersCacheModel())->UpdateData($order_id, ['trade_type' => $trade_type, 'account' => $account]);
                // 删除旧订单缓存
                (new OrdersModel())->rm_cache(['oid' => $oid, 'del_add' => 0, 'order_id' => $order_id, 'uid' => $this->user['id'], 'gid' => $map['gid'] ?? 0]);
            }
            catch (Exception $e)
            {
                return show(config('code.error'), $e->getMessage(), [], 500);
            }

            //支付订单
            $data = $OrdersLib->unifyPayOrder(['oid' => $oid, 'order_type' => $num, 'trade_type' => $trade_type, 'total_amount' => $total_amount, 'pay_des' => $pay_des, 'order_id' => $order_id, 'openid' => $openid, 'callback_url' => $callback_url], 1);

            $data['data']['skuId'] = implode(',', $gid);

            return show(config('code.success'), '下单成功', $data['data']);
        }

        return show(config('code.error'), '当前订单不存在');
    }

    /**
     * 检测下单参数
     * @param $param
     * @return string
     * @throws Exception
     */
    private function CheckUnlock($param)
    {
        $this->msg = '';
        if (!$param['rids'])
        {
            return $this->msg = '缺少档案信息';
        }
        $recodes = (new \app\common\cachemodel\Recode())->batchGetInfoByIds($param['rids']);
        if (!$recodes)
        {
            return $this->msg = '档案不存在';
        }
        foreach ($recodes as $recode)
        {
            if ($recode['uid'] != $this->user['id'])
            {
                return $this->msg = '服务异常';
            }
            if ((int)$recode['status'] === 0)
            {
                return $this->msg = '档案已删除';
            }
        }
        if (!$param['time'])
        {
            return $this->msg = '请选择时间';
        }
        if ($param['time'] < 0)
        {
            return $this->msg = '时间错误';
        }
        if (!in_array($param['trade_type'], [1, 2], true))
        {
            return $this->msg = '未知的支付方式';
        }
        if (!in_array($param['gid'], config('goods.day_id'), true))
        {
            return $this->msg = '未知的商品';
        }
        return $this->msg;
    }
}
